<template>
  <div class="pop-science">
    <div class="content">
      <ul v-for="item in state.list" :key="item.id">
        <li>
          <img style="width: 100px; height: 100px" :src="item.avatar" alt="" />
        </li>
        <li>{{ item.id }}:{{ item.name }}</li>
      </ul>
      <!-- loading  -->
      <div ref="boxRef" class="loading">...</div>
    </div>
  </div>
</template>
<script lang="ts">
import {
  defineComponent,
  reactive,
  nextTick,
  onMounted,
  ref,
  watchEffect
} from 'vue'
// 模拟数据
const createData = ({ page = 1, size = 10 }) => {
  let arr: any[] = []
  return new Promise((resolve, reject) => {
    for (let i = 0; i < 1000; i++) {
      arr.push({
        id: i + 1,
        name: `city: ${i + 1} week`,
        avatar: `https://www.robohash.org/${i}`
      })
    }
    setTimeout(() => {
      resolve(arr.slice((page - 1) * size, page * size))
    }, 2000)
    // page * size
    // page - 1 * size
  })
}

interface StateProps {
  list: any[]
  pageOpt: {
    page: number
    size: number
  }
  loading: boolean
}

export default defineComponent({
  setup(props, context) {
    // 初始化时间
    const state = reactive<StateProps>({
      list: [], // 列表数据
      pageOpt: {
        // 分页参数
        page: 1,
        size: 10
      },
      loading: false // loading控制
    })
    // loading盒子
    const boxRef = ref<HTMLElement | null>(null)

    // 声明周期
    onMounted(() => {
      getData({})
    })

    // 监听dom是否出现在- 可是区域窗口-内部函数
    const handleObserver = () => {
      const callback = (entries: any[]) => {
        if (entries[0].intersectionRatio <= 0) return
        if (!state.loading && entries[0].isIntersecting) {
          console.log('进入视图：', entries[0].isIntersecting)
          state.pageOpt.page++
          getData({ page: state.pageOpt.page })
        }
      }

      // 初始化监听函数- 说明当前的观察函数是一个异步函数
      const io = new IntersectionObserver(callback, {
        threshold: [1] // [0, .2, .5, .8, 1]
      })

      // 开始观察
      if (boxRef.value) {
        io.observe(boxRef.value)
      }

      // // 停止观察
      // io.unobserve(boxRef.value)
      // // 关闭观察器
      // io.disconnect()
    }

    // 获取数据
    const getData = async ({ page = state.pageOpt.page }) => {
      // 出现loading 开关
      state.loading = true
      // 请求数据
      let data = await createData({ page })
      // 关闭laoding
      state.loading = false
      // 拼接数据
      state.list = state.list.concat(data)

      await nextTick() //
      // 操作都dom 监听dom.监听 loading是否出现，如果loading出现了，说明，滑动到了底部，说明当前数据加载完成，应该请求下一次加载数据
      handleObserver()
    }
    return {
      state,
      boxRef
    }
  }
})
</script>
<style scoped lang="scss">
.pop-science {
  width: 100%;
  height: 100%;
  overflow: auto;
  scroll-behavior: smooth;
}
.loading {
  margin: 10px auto;
  background: #ccc;
  text-align: center;
  line-height: 15px;
  width: 25px;
  height: 25px;
  animation: circle 1s linear infinite;
  transform-origin: 50% 50%; // 定义动画的旋转中心点
}
@keyframes circle {
  0% {
    transform: rotate(0);
  }
  50% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
